#ifndef SLICERWIDGET_H
#define SLICERWIDGET_H

#include "VisWidgetBase.h"

#include "vtkImageResliceMapper.h"
#include "vtkImageSlice.h"
#include "vtkLookupTable.h"
#include "vtkImageMapToColors.h"
#include "vtkInteractorStyleImage.h"
#include "vtkArrowSource.h"
#include "vtkWorldPointPicker.h"
#include "vtkRendererCollection.h"
#include "vtkLineWidget2.h"
#include "vtkCommand.h"

#include "vtkPointHandleRepresentation2D.h"
#include "vtkFocalPlanePointPlacer.h"
#include "vtkHandleWidget.h"
#include "vtkPolyData.h"

#include <QMessageBox>
#include <QWheelEvent>
#include <QObject>
#include <QPoint>
#include <QPaintEngine>
#include <QVector>

class HandleCallback;

class SlicerWidget : public VisWidgetBase
{
    Q_OBJECT

public:
    typedef vtkSmartPointer<vtkImageResliceMapper> ResliceMapperPointer;
    typedef vtkSmartPointer<vtkImageSlice> SliceActorPointer;
    typedef vtkSmartPointer<vtkImageProperty> DisplayImagePropertyPointer;

    typedef vtkSmartPointer<vtkLookupTable> LookupTablePointer;
    typedef vtkSmartPointer<vtkImageMapToColors> ImageMapToColorsPointer;

    typedef vtkSmartPointer<vtkArrowSource> ArrowSourcePointer;

    typedef vtkSmartPointer<vtkHandleWidget> HandleWidgetPointer;
    typedef vtkSmartPointer<vtkPointHandleRepresentation2D> HandleRepPoiter;
    typedef vtkSmartPointer<vtkFocalPlanePointPlacer> PointPlacerPointer;
    typedef vtkSmartPointer<HandleCallback> HandleCallbackPointer;

    typedef vtkSmartPointer<vtkPolyData> PolyDataPointer;

    SlicerWidget(VisWidgetType type, QWidget* parent = NULL);
    ~SlicerWidget();

    void SetImage(DisplayImageType* inputImage, ImageProperties *imageProperties);
    virtual void SetTransformMatrix(TransformMatrixType *transformMatrix);

    void SetVolume(Material *material, DisplayImagePointer volumeImage);

    PolyDataPointer CreateCursor();

    void wheelEvent(QWheelEvent *event);
    void moveCrosshairs();

    static void LeftButtonPressed(vtkObject* object, unsigned long eid, void* clientdata, void *calldata);

    VisWidgetType GetWidgetType()
    { return m_WidgetType; }

    QPaintEngine* paintEngine() const
    { return QWidget::paintEngine(); }

signals:
    void PointChanged(double* pos);

public slots:
    void ChangeOwnPoint(double* pos);
    void ChangePoint(double* pos);

private:
    TransformMatrixPointer m_FinalMatrix;

    DisplayImagePointer m_GreyDisplayImage;
    LookupTablePointer m_GreyLookupTable, m_RGBLookupTable;
    ImageMapToColorsPointer m_GreyImageMapToColors;

    ResliceMapperPointer m_GreyResliceMapper;
    SliceActorPointer m_GreyActor;

    QPoint m_HairPosition;

    HandleRepPoiter m_HandleRep;
    PointPlacerPointer m_PointPlacer;
    HandleWidgetPointer m_HandleWidget;
    HandleCallbackPointer m_HandleCallback;
};

class HandleCallback : public vtkCommand
{
  public:
    static HandleCallback *New()
    {
      return new HandleCallback;
    }

    virtual void Execute(vtkObject *caller, unsigned long eid, void* clientdata)
    {

        vtkHandleWidget *handleWidget = static_cast<vtkHandleWidget*>(caller);
        double pos[3];
        static_cast<vtkHandleRepresentation *>(handleWidget->GetRepresentation())->GetDisplayPosition(pos);

        m_Widget->ChangeOwnPoint(pos);
    }

    void SetWidget(SlicerWidget* widget)
    { m_Widget = widget; }

    HandleCallback(){}

private:
    SlicerWidget* m_Widget;
};

#endif
